package com.harmony.pilot.data.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * CodeQL查询管理器
 * 负责加载和管理自定义查询文件
 */
@Slf4j
@Component
public class CodeQLQueryManager {
    
    @Value("${codeql.queries-path:../codeql-custom-queries-cpp}")
    private String queriesPath;
    
    // 查询文件缓存：queryId -> queryContent
    private final Map<String, String> queryCache = new ConcurrentHashMap<>();
    
    // 查询信息：queryId -> QueryInfo
    private final Map<String, QueryInfo> queryInfoCache = new ConcurrentHashMap<>();
    
    /**
     * 初始化：加载所有查询文件
     */
    public void initialize() {
        log.info("Initializing CodeQL Query Manager from: {}", queriesPath);
        loadQueryFiles();
    }
    
    /**
     * 加载所有查询文件
     */
    private void loadQueryFiles() {
        Path queriesDir = Paths.get(queriesPath);
        
        if (!Files.exists(queriesDir) || !Files.isDirectory(queriesDir)) {
            log.warn("CodeQL queries directory not found: {}", queriesPath);
            return;
        }
        
        try (Stream<Path> paths = Files.walk(queriesDir)) {
            paths.filter(Files::isRegularFile)
                 .filter(p -> p.toString().endsWith(".ql"))
                 .forEach(this::loadQueryFile);
        } catch (IOException e) {
            log.error("Failed to load query files from: {}", queriesPath, e);
        }
        
        log.info("Loaded {} CodeQL queries", queryCache.size());
    }
    
    /**
     * 加载单个查询文件
     */
    private void loadQueryFile(Path queryPath) {
        try {
            String queryId = generateQueryId(queryPath);
            String content = Files.readString(queryPath);
            
            queryCache.put(queryId, content);
            
            // 解析查询信息（从注释中提取）
            QueryInfo info = parseQueryInfo(queryPath, content);
            queryInfoCache.put(queryId, info);
            
            log.debug("Loaded query: {} from {}", queryId, queryPath);
        } catch (IOException e) {
            log.error("Failed to load query file: {}", queryPath, e);
        }
    }
    
    /**
     * 生成查询ID（相对路径，不含扩展名）
     */
    private String generateQueryId(Path queryPath) {
        Path queriesDir = Paths.get(queriesPath);
        Path relativePath = queriesDir.relativize(queryPath);
        String queryId = relativePath.toString().replace(".ql", "").replace(File.separator, "/");
        return queryId;
    }
    
    /**
     * 解析查询信息（从QL文件的注释中提取）
     */
    private QueryInfo parseQueryInfo(Path queryPath, String content) {
        QueryInfo info = new QueryInfo();
        info.setId(generateQueryId(queryPath));
        info.setPath(queryPath.toString());
        
        // 解析 @name, @kind, @description 等注释
        String[] lines = content.split("\n");
        for (String line : lines) {
            line = line.trim();
            if (line.startsWith("@name")) {
                info.setName(extractValue(line));
            } else if (line.startsWith("@kind")) {
                info.setKind(extractValue(line));
            } else if (line.startsWith("@description")) {
                info.setDescription(extractValue(line));
            } else if (line.startsWith("@id")) {
                info.setId(extractValue(line));
            }
        }
        
        // 如果没有找到名称，使用文件名
        if (info.getName() == null || info.getName().isEmpty()) {
            String fileName = queryPath.getFileName().toString().replace(".ql", "");
            info.setName(fileName);
        }
        
        return info;
    }
    
    /**
     * 从注释行中提取值
     * 例如: "@name Hello world" -> "Hello world"
     */
    private String extractValue(String line) {
        int colonIndex = line.indexOf(" ");
        if (colonIndex > 0) {
            return line.substring(colonIndex + 1).trim();
        }
        return "";
    }
    
    /**
     * 获取查询内容
     */
    public String getQuery(String queryId) {
        return queryCache.get(queryId);
    }
    
    /**
     * 获取查询信息
     */
    public QueryInfo getQueryInfo(String queryId) {
        return queryInfoCache.get(queryId);
    }
    
    /**
     * 列出所有可用查询
     */
    public List<QueryInfo> listQueries() {
        return new ArrayList<>(queryInfoCache.values());
    }
    
    /**
     * 按类型过滤查询
     */
    public List<QueryInfo> listQueriesByKind(String kind) {
        return queryInfoCache.values().stream()
                .filter(q -> kind.equals(q.getKind()))
                .collect(Collectors.toList());
    }
    
    /**
     * 检查查询是否存在
     */
    public boolean hasQuery(String queryId) {
        return queryCache.containsKey(queryId);
    }
    
    /**
     * 重新加载查询文件
     */
    public void reload() {
        queryCache.clear();
        queryInfoCache.clear();
        loadQueryFiles();
    }
    
    /**
     * 查询信息DTO
     */
    public static class QueryInfo {
        private String id;
        private String name;
        private String kind;
        private String description;
        private String path;
        
        // Getters and Setters
        public String getId() { return id; }
        public void setId(String id) { this.id = id; }
        
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public String getKind() { return kind; }
        public void setKind(String kind) { this.kind = kind; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public String getPath() { return path; }
        public void setPath(String path) { this.path = path; }
    }
}

